var target = UIATarget.localTarget();

var app = target.frontMostApp();
var window = app.mainWindow();

//---------------------
//ELEMENT HELPER FUNCTION:
//---------------------

function getElement(elementIdentifier, elementType, elementLocation){
    var element;
    
    if (elementLocation == "Navigation Bar") {
        element = window.navigationBar().elements().firstWithName(elementIdentifier);
    } else if (elementLocation == "Table Cell") {
        element = window.tableViews()[0].cells().firstWithName(elementIdentifier);
    } else if (elementLocation == "Table Cell TextField") {
		element = window.tableViews()[0].elements().firstWithName(elementIdentifier).textFields()[0];
	} else if (elementLocation == "TableView Header") {
		element = window.tableViews()[0].elements().firstWithName(elementIdentifier);
    } else if (elementLocation == "Action Sheet") {
        element = app.actionSheet().elements().firstWithName(elementIdentifier);
	} else {//elementLocation == "Window") {
        element = window.elements().firstWithName(elementIdentifier);
    }
    
    return element;
}

function getValidElement(elementIdentifier, elementType, elementLocation) {
    var element;
    
    //first, find the element with identifier name in the location specified:
    element = getElement(elementIdentifier, elementType, elementLocation)
    
	UIALogger.logMessage("checking...element=" + element);
    //second, make sure this found element is of the right type:
    
    //fail if the element cannot be found:
    if (!(element instanceof elementType)) {
        UIALogger.logFail("Could not find element with name=" + elementIdentifier 
                          + " type=" + elementType + " location=" + elementLocation);
    }
    
    return element;
}

function getElementByPredicateValue(elementValue, elementType, elementLocation) {
    var element;
    
    //first, find the element with identifier name in the location specified:
    if (elementLocation == "Navigation Bar") {
        element = window.navigationBar().elements().firstWithPredicate("value beginsWith '" + elementValue + "'");
    } else if (elementLocation == "Table Cell") {
        element = window.tableViews()[0].cells().firstWithPredicate("value beginsWith '" + elementValue + "'");
    } else if (elementLocation == "Table Cell TextField") {
		element = window.tableViews()[0].elements().firstWithPredicate("value beginsWith '" + elementValue + "'");
	} else if (elementLocation == "TableView Header") {
		element = window.tableViews()[0].elements().firstWithPredicate("value beginsWith '" + elementValue + "'");
    } else if (elementLocation == "Action Sheet") {
        element = app.actionSheet().elements().firstWithPredicate("value beginsWith '" + elementValue + "'");
	} else {//elementLocation == "Window") {
        element = window.elements().firstWithPredicate("value beginsWith '" + elementValue + "'");
    }
    
    return element;
}

function getElementByPredicateName(elementName, elementType, elementLocation) {
    var element;
    
    //first, find the element with identifier name in the location specified:
    if (elementLocation == "Navigation Bar") {
        element = window.navigationBar().elements().firstWithPredicate("name beginsWith '" + elementName + "'");
    } else if (elementLocation == "Table Cell") {
        element = window.tableViews()[0].cells().firstWithPredicate("name beginsWith '" + elementName + "'");
    } else if (elementLocation == "Table Cell TextField") {
		element = window.tableViews()[0].elements().firstWithPredicate("name beginsWith '" + elementName + "'");
	} else if (elementLocation == "TableView Header") {
		element = window.tableViews()[0].elements().firstWithPredicate("name beginsWith '" + elementName + "'");
    } else if (elementLocation == "Action Sheet") {
        element = app.actionSheet().elements().firstWithPredicate("name beginsWith '" + elementName + "'");
	} else {//elementLocation == "Window") {
        element = window.elements().firstWithPredicate("name beginsWith '" + elementName + "'");
    }
    
    return element;
}


//---------------------
//UI ELEMENT NAME HELPER FUNCTIONS:
//---------------------

function getElementName(elementIdentifier, elementType, elementLocation) {
    return (getValidElement(elementIdentifier, elementType, elementLocation)).name();
}

function setElementName(elementIdentifier, elementType, elementLocation, newName) {
    var element = getValidElement(elementIdentifier, elementType, elementLocation);
    element.setName(newName);
}

//---------------------
//UI ELEMENT VALUE HELPER FUNCTIONS:
//---------------------

function getElementValue(elementIdentifier, elementType, elementLocation) {
    return (getValidElement(elementIdentifier, elementType, elementLocation)).value();
}

function setElementValue(elementIdentifier, elementType, elementLocation, newValue) {
    var element = getValidElement(elementIdentifier, elementType, elementLocation);
    element.setValue(newValue);
}

//---------------------
//TAP UI ELEMENTS:
//---------------------

function tapElement(elementIdentifier, elementType, elementLocation, optionAfterTap) {
    var elementToTap = getValidElement(elementIdentifier, elementType, elementLocation);
    
    elementToTap.tap();
    
    if (optionAfterTap == "WaitForInvalid") {
        elementToTap.waitForInvalid();
    } else if (optionAfterTap == "Delay 5 Seconds") {
    	target.delay(5);
    } else { //(optionAfterTap == "Delay") 
        target.delay(2);
    }
}

function doubleTapElement(elementIdentifier, elementLocation, optionAfterTap) {
    var elementToTap = getValidElement(elementIdentifier, elementLocation);
    
    elementToTap.doubleTap();
    
    if (optionAfterTap == "WaitForInvalid") {
        elementToTap.waitForInvalid();
    } else if (optionAfterTap == "5 Second Delay") {
        target.delay(5);
    } else { //(optionAfterTap == "2 Second Delay") 
        target.delay(2);
    }
}

//---------------------
//VERIFY UI ELEMENT NAME ATTRIBUTE:
//---------------------

function verifyElementName(elementIdentifier, elementType, elementLocation, expectedName) {
    var actualName = getElementName(elementIdentifier, elementType, elementLocation);
    return expectedName == actualName;
}

//---------------------
//VERIFY UI ELEMENT VALUE ATTRIBUTE:
//---------------------

function verifyElementValue(elementIdentifier, elementType, elementLocation, expectedValue) {
    var actualValue = getElementValue(elementIdentifier, elementType, elementLocation);
    return expectedValue == actualValue;
}

//---------------------
//VERIFY UI ELEMENT VALID WITH 'NAME BEGINSWITH':
//---------------------

function verifyElementValidByName(elementName, elementType, elementLocation) {
    var element = getElementByPredicateName(elementName, elementType, elementLocation);
    return element.isValid();
}

//---------------------
//VERIFY UI ELEMENT VALID WITH 'VALUE BEGINSWITH':
//---------------------

function verifyElementValidByValue(elementValue, elementType, elementLocation) {
    var element = getElementByPredicateValue(elementValue, elementType, elementLocation);
    return element.isValid();
}

//---------------------
//VERIFY NAVIGATION BAR TITLE:
//---------------------

function verifyNavBarTitle(expectedTitle) {
    var actualTitle = window.navigationBar().staticTexts()[0].name();
    return expectedTitle == actualTitle;
}

//---------------------
//TYPE STRING WITH KEYBOARD:
//---------------------

function typeStringWithKeyboard(stringToType) {
    if (app.keyboard()) {
        app.keyboard().typeString(stringToType);
    } else {
        UIALogger.logFail("Could not type with keyboard because the keyboard is not available.");
    }
}

//---------------------
//SPECIFIC TAPPING ACTIONS:
//---------------------

function tapCancelOnActionSheet() {
    var elementToTap = app.actionsheet().cancelButton();
    
    elementToTap.tap();
    elementToTap.waitForInvalid();
}

function tapBackNavigationButton() {
    var elementToTap = window.navigationBar().leftButton();
    if (elementToTap.isValid()) {
        elementToTap.tap();
        elementToTap.waitForInvalid();
    } else {
        UIALogger.logFail("TapBackNavigationButton failed because the navigation bar's left side button is not valid.");
    }
}

function swipeToDeleteAction(tableCellIdentifier) {
    var elementToDelete = getValidElement(tableCellIdentifier, UIATableCell, "Table Cell");
    if (elementToDelete.isValid()) {
        var deleteSwitch = elementToDelete.switches()["Delete " + elementToDelete.name()];
        deleteSwitch.tap();
        target.delay(2);
        var deleteButton = elementToDelete.buttons()[0];
        deleteButton.tap();
        target.delay(2);
    } else {
        UIALogger.logFail("SwipeToDelete failed because table cell provided is not valid.");
    }
}

function tapInsertSwitch(elementIdentifier) {
	var elementToTap = getValidElement(elementIdentifier, UIATableCell, "Table Cell");
	elementToTap.tap();
	target.delay(2);
}

//---------------------
//LOGGING FUNCTIONALITY:
//---------------------

function logElementTree() {
    app.logElementTree();
}

function logMessage(message) {
    UIALogger.logMessage(message);
}
                          
function logTestResult(actualValue, expectedTrueValue, message) {
    if (actualValue == expectedTrueValue) {
        passTest(message);
    } else {
        failTest(message);
    }
}
                          
function passTest(message) {
	UIALogger.logPass(message);
}

function failTest(message) {
    UIALogger.logFail(message);
}